<!DOCTYPE html>
<html lang="en">
	<head>
		<meta charset="utf-8" />
		<meta name="viewport" content="width=device-width, initial-scale=1" />
		<title>Template • TodoMVC</title>
		<link rel="stylesheet" href="node_modules/todomvc-common/base.css" />
		<link rel="stylesheet" href="node_modules/todomvc-app-css/index.css" />
		<link rel="stylesheet" href="css/app.css" />
		<script src="lib/react/react.development.js"></script>
		<script src="lib/react/react-dom.development.js"></script>
		<script src="lib/babel.min.js"></script>
	</head>
	<body>
		<section class="todoapp" id="root"></section>
		<footer class="info">
			<p>Double-click to edit a todo</p>
			<p>Template by <a href="http://sindresorhus.com">Sindre Sorhus</a></p>
			<p>Created by <a href="http://todomvc.com">you</a></p>
			<p>Part of <a href="http://todomvc.com">TodoMVC</a></p>
		</footer>
		<script src="node_modules/todomvc-common/base.js"></script>
		<script type="text/babel">
		 	// 1. <TodoMVC />  <TodoItem />  <FooterBar /> 三个组件.
			 // 注意状态提升!注意要修改props,必须从"数据源"进行修改.
			class TodoItem extends React.Component {
				constructor(props){
					super(props);
					this.state = {
						preEditValue: '', // 备份编辑框内容
					}
				}
				handleItemCheckedChange = (id)=>{
					// 问题是 能直接修改 props.item.isCompleted 吗?? 不能的!!!
					// 在react中,子组件想要修改父组件的props,就必须通过在"数据源头"进行修改.
					this.props.handleItemCheckedChange(id);
				}
				// 修改为编辑状态
				setItemEdit = (id,e)=>{
					var inputDom = e.target.parentNode.nextElementSibling;
					// 同步输入框的内容为输入的文本
					this.setState({
						preEditValue: this.props.item.text
					})
					this.props.setItemEdit(id,()=>{
						inputDom.focus();
					});
				}
				// 输入框发生变化触发
				handleInputChange =(key,e)=>{
					var value = e.target.value;
					this.setState({
						[key]:value
					})
				}
				handleEditSaveOrEsc = (e)=>{
					// id可以直接从props获取也可以传递
					var id = this.props.item.id;
					var keyCode = e.keyCode;
					// 回车  需要修改到父组件
					if(keyCode == 13){
						// 修改值 
						var value = e.target.value;
						this.props.handleEditSave(id,value);
					}
					if(keyCode == 27 ){
						// 取消
						this.setState({
							preEditValue: this.props.item.text
						})
						// 从父类改变editId的值 同时取消编辑状态
						this.props.setItemEdit('');
					}
				}
				removeItem = (id)=>{
					this.props.removeItem(id);
				}
				render(){
					// 对象解构
					var {id,text,isCompleted} = this.props.item;
					var className = isCompleted?"completed":"";
					// 修改是否处于编辑状态
					className += (this.props.editId == id ? " editing": "");
					return (
						<li className={className}>
							<div className="view">
								<input className="toggle" type="checkbox" checked = {isCompleted} onChange={()=>this.handleItemCheckedChange(id)}/>
								<label onDoubleClick={e=>this.setItemEdit(id,e)}>{text}</label>
								<button className="destroy" onClick={()=>this.removeItem(id)}></button>
							</div>
							<input className="edit" value={this.state.preEditValue} onChange={e=>this.handleInputChange('preEditValue',e)} onKeyUp={this.handleEditSaveOrEsc}/>
						</li>
					)
				}
			}
			class FooterBar extends React.Component {
				constructor(props){
					super(props);
				}
				doClearCompleted =()=>{
					this.props.doClearCompleted();
				}
				handleFilterChange =(filterState)=>{
					this.props.changeFilterState(filterState);
				}
				render(){
					var filterState = this.props.filterState
					return (
						<footer className="footer">
								{/* This should be `0 items left` by default */}
								<span className="todo-count">
									<strong>{this.props.lastCount}</strong> item left
								</span>
								{/* Remove this if you don't implement routing */}
								<ul className="filters">
									<li>
											<a className={filterState=='All'?"selected":""} href="#/" onClick={()=>this.handleFilterChange('All')}>All</a>
										</li>
										<li>
											<a className={filterState=='Active'?"selected":""} href="#/active" onClick={()=>this.handleFilterChange('Active')}>Active</a>
										</li>
										<li>
											<a className={filterState=='Completed'?"selected":""} href="#/completed" onClick={()=>this.handleFilterChange('Completed')}>Completed</a>
										</li>
								</ul>
								{/* Hidden if no completed items are left ↓ */}
								<button className="clear-completed" onClick={this.doClearCompleted}>Clear completed</button>
							</footer>
					)
				}
			}
			
			class TodoMVC extends React.Component {
				constructor(props){
					super(props);
					// 状态提升
					this.state = {
							newTodoText: '', // 新增的todo文本
							editId: '', // 编辑的id
							filterState: 'All', // 过滤条件 All   Active  Completed
							todoList: [ 
								{
									id: '1',
									text: '吃饭',
									isCompleted: true
								},
								{
									id: '2',
									text: '上班',
									isCompleted: false
								}
							]
						}
				}
				handleInputChange = (key,e)=>{
					var value = e.target.value;
					this.setState({
						[key]: value
					})
				}
				handleNewTodoInputKeyUp = (e)=>{
					var keyCode = e.keyCode;
					var value = e.target.value;
					if(value == '') return;
					// 如果是enter=13需要添加
					if(keyCode == 13){
						var todoList = [...this.state.todoList];
						//构建todo
						todoList.push({
							id: new Date().getTime().toString(),
							text: value,
							isCompleted: false
						})
						// 添加
						this.setState({
							todoList
						})
						// 清空
						this.setState({
							newTodoText: ''
						})
					}
					// 如果是esc=27  需要取消
					if(keyCode == 27){
						this.setState({
							newTodoText: ''
						})
					}
				}
				// 用于处理item的checked变化
				handleItemCheckedChange = (id)=>{
					// 只需要知道id,因为checked变化是一个toggle状态,我们在这里只需要修改为"非"状态即可
					var todoList = [...this.state.todoList];
					var todoItem = todoList.find(item=> item.id == id);
					todoItem.isCompleted = !todoItem.isCompleted;
					// 修改到state
					this.setState({
						todoList
					})
				}
				// 当全选反选按钮被点击的时候触发
				handleAllCheckedChange = ()=>{
						// 1. 获取之前的状态
						var preIsAllCompleted = !this.state.todoList.some(item=>!item.isCompleted);
						// 2. 修改所有的列表使其和 preIsAllCompleted 相反
						var todoList = [...this.state.todoList];
						var newTodoList = todoList.map(item=>{
							item.isCompleted = !preIsAllCompleted;
							return item;
						})
						// 3. 修改state
						this.setState({
							todoList: newTodoList
						})
				}
				// 保存编辑内容
				handleEditSave = (id,text)=>{
					var todoList = [...this.state.todoList];
					var todoItem = todoList.find(item=> item.id == id);
					todoItem.text = text;
					// 3. 修改state
					this.setState({
						todoList,
						editId: ''
					})
				}

				// 修改编辑的标识 
				// 如果希望状态发生变化后使某个元素有焦点,可以用callback回调处理
				setItemEdit=(id,callback)=>{
					this.setState((state,props)=>(
						{editId: id}
					),()=>{
						if(callback){
							callback();
						}
					})
				}
				// 删除item
				removeItem = (id)=>{
					var todoList = [...this.state.todoList];
					var newTodoList = todoList.filter(item=> item.id != id);
					this.setState({
						todoList: newTodoList
					})
				}
				// 删除所有完成数据
				doClearCompleted = ()=>{
						var todoList = [...this.state.todoList];
						var newTodoList = todoList.filter(item => !item.isCompleted);
						this.setState({
							todoList: newTodoList
						})
				}
				// 修改状态
				changeFilterState =(state)=>{
					this.setState({
						filterState: state
					})
				}
				render() {
					// TodoItem列表
					var liList = this.state.todoList.map(item=>{
							// 1. 如果是active状态 过滤掉所有的已完成
							if(this.state.filterState == 'Active'){
								if(item.isCompleted) return null;
							}else 
							// 2. 如果是
							if(this.state.filterState == 'Completed'){
								if(!item.isCompleted) return null;
							}
							return(
								<TodoItem key={item.id} item={item} editId={this.state.editId} handleItemCheckedChange={this.handleItemCheckedChange} handleEditSave={this.handleEditSave} setItemEdit={this.setItemEdit} removeItem={this.removeItem}/>
							)
						}
					)
					// 判断是否全选中  some()可以判断列表是否存在没有完成的项目
					var isAllCompleted = !this.state.todoList.some(item=>!item.isCompleted);
					// 剩余未完成数量
					var lastCount = this.state.todoList.filter(item=>!item.isCompleted).length;
					return (
						<div>
							<header className="header">
								<h1>todos-v2</h1>
								<input
									className="new-todo"
									placeholder="What needs to be done?"
									value={this.state.newTodoText}
									onChange={e=>this.handleInputChange('newTodoText',e)}
									onKeyUp={this.handleNewTodoInputKeyUp}
									autoFocus
								/>
							</header>
							{/* This section should be hidden by default and shown when there are todos */}
							<section className="main">
								<input id="toggle-all" className="toggle-all" type="checkbox" checked={isAllCompleted} onChange={this.handleAllCheckedChange}/>
								<label htmlFor="toggle-all">Mark all as complete</label>
								<ul className="todo-list">
									{/* These are here just to show the structure of the list items */}
									{/* List items should get the class `editing` when editing and `completed` when marked as completed */}
									{liList}
								</ul>
							</section>
							<FooterBar lastCount={lastCount} filterState={this.state.filterState} doClearCompleted={this.doClearCompleted} changeFilterState={this.changeFilterState}/>
						</div>
					);
				}
			}
			ReactDOM.render(<TodoMVC />, document.getElementById("root"));
		</script>
	</body>
</html>
